package com.maiji.cloud.service.impl;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.maiji.cloud.config.MyRedisConfig;
import com.maiji.cloud.entities.shopingmall.CapitalMain;
import com.maiji.cloud.mapper.*;
import com.maiji.cloud.microservice.CapitalMainMService;
import com.maiji.cloud.request.BaseDataReqDto;
import com.maiji.cloud.request.BaseInputDto;
import com.maiji.cloud.request.IdInputDto;
import com.maiji.cloud.request.ReqMetaData;
import com.maiji.cloud.mapper.ForwardingRecordsMapper;
import com.maiji.cloud.mapper.ForwardingRecordshelpMapper;
import com.maiji.cloud.mapper.SignInDeployMapper;
import com.maiji.cloud.mapper.UploadRecordMapper;
import com.maiji.cloud.request.login.*;
import com.maiji.cloud.response.*;
import com.maiji.cloud.response.login.*;
import com.maiji.cloud.service.UploadRecordService;
import com.maiji.cloud.service.WeightChangeLogService;
import com.maiji.cloud.utils.*;

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jetty.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.fastjson.JSON;
import com.maiji.cloud.entities.login.AppUser;
import com.maiji.cloud.entities.login.DistributionRuleConfigEntity;
import com.maiji.cloud.entities.login.ForwardingRecordsEntity;
import com.maiji.cloud.entities.login.ForwardingRecordsHelpEntity;
import com.maiji.cloud.entities.login.KetonuriaChangeLog;
import com.maiji.cloud.entities.login.LoginLog;
import com.maiji.cloud.entities.login.ReduceWeightFundLogEntity;
import com.maiji.cloud.entities.login.ShareWeightHelpRule;
import com.maiji.cloud.entities.login.ShareWeightRuleEntity;
import com.maiji.cloud.entities.login.SignInDeployEntity;
import com.maiji.cloud.entities.login.StageConfigEntity;
import com.maiji.cloud.entities.login.UploadRecord;
import com.maiji.cloud.entities.login.UserInfo;
import com.maiji.cloud.entities.login.UserSignInEntity;
import com.maiji.cloud.entities.login.UserStageEntity;
import com.maiji.cloud.entities.login.WeightChangeLog;
import com.maiji.cloud.mapper.UserInfoMapper;
import com.maiji.cloud.mapper.UserSignInMapper;
import com.maiji.cloud.mapper.WeightChangeLogMapper;
import com.maiji.cloud.request.shopingmall.DistributeFundReqDto;
import com.maiji.cloud.request.shopingmall.DistributeFundReqDto.DistributeFundReqData;
import com.maiji.cloud.request.shopingmall.DistributeIntegralReqDto;
import com.maiji.cloud.request.shopingmall.DistributeIntegralReqDto.DistributeIntegralReqData;
import com.maiji.cloud.request.shopingmall.DistributionLogListReqDto;
import com.maiji.cloud.response.login.DistributionSumResDto.DistributionSumResData;
import com.maiji.cloud.service.AppUserService;
import com.maiji.cloud.service.UserService;
import com.maiji.cloud.service.shopping.IntegralService;

@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserService {

	private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    @Autowired
    private RedisTemplate<String, Object> maiji1RedisTemplate;
    @Autowired
    private AppUserService appUserService;
	@Autowired
	private UserInfoMapper userInfoMapper;
	@Autowired
	private WeightChangeLogMapper weightChangeLogMapper;
	@Autowired
	private AppUserMapper appUserMapper;
	@Autowired
	private SignInDeployMapper signInDeployMapper;
	@Autowired
	private UserSignInMapper userSignInMapper;
	@Autowired
	private IntegralService integralService;
	@Autowired
	private ForwardingRecordsMapper forwardingRecordsMapper;
	@Autowired
	private ForwardingRecordshelpMapper forwardingRecordshelpMapper;
	@Autowired
	private CapitalMainMService capitalMainMService;
	@Autowired
	private UploadRecordService uploadRecordService;
	@Autowired
	private MongoTemplate mongoTemplate;
	@Autowired
	private ReduceWeightFundLogMapper reduceWeightFundLogMapper;
	@Autowired
	private KetonuriaChangeLogMapper ketonuriaChangeLogMapper;
	@Autowired
	private UserStageMapper userStageMapper;
	@Autowired
	private StageConfigMapper stageConfigMapper;
	@Autowired
	private WeightChangeLogService weightChangeLogService;
	@Value("${domain.name}")
	private String webUrl;
	
	@Value("${longTimeLogIn}")
	private Integer longTimeLogIn;

	@Autowired
	private LoginLogMapper loginLogMapper;

	@SuppressWarnings("unused")
	@Override
	public BaseResDto setingUserInfo(SetUserInfoReqDto setUserInfoReqDto) throws Exception {
		// 获得用户id
		AppUser appUser = appUserService.checkToken(setUserInfoReqDto.getData().getMaijiToken());

		if (appUser == null) {
			logger.info("UserServiceImpl.setingUserInfo,appUser is {}", JSON.toJSONString(appUser));
			BaseResDto.baseResDto(Status.PARAMETERERROR, "token 无效 ");
		}

		UserStageEntity userStageEntity = userStageMapper.selectOneByUserId(appUser.getUuId());
		if (setUserInfoReqDto.getData().getStage() == null) {
			userStageEntity = new UserStageEntity();
			userStageEntity.setUuId(UUID_MD5.getUUID());
			userStageEntity.setUserId(appUser.getUuId());
			userStageEntity.setCurrentStage(CommonIntValueEnum.STAGE_ONE.getValue());
			userStageEntity.setInTime(new Date());
			
			EntityWrapper<UserStageEntity> wrapper = new EntityWrapper<UserStageEntity>();
			wrapper.eq("user_id", appUser.getUuId());
			// 删除之前的阶段记录
			userStageMapper.delete(wrapper);
			userStageMapper.insert(userStageEntity);
		}

		if (setUserInfoReqDto.getData().getStage() != null) {
			if(setUserInfoReqDto.getData().getStage() == 0)setUserInfoReqDto.getData().setStage(CommonIntValueEnum.STAGE_ONE.getValue());
			if(setUserInfoReqDto.getData().getDay() == 0)setUserInfoReqDto.getData().setDay(1);
			if (userStageEntity != null) {
				Integer days = TimeUtil.daysBetween(userStageEntity.getInTime(), new Date()) + 1;
				if (!(days.equals(setUserInfoReqDto.getData().getDay())
						&& setUserInfoReqDto.getData().getStage() == userStageEntity.getCurrentStage())) {
					userStageEntity.setCurrentStage(setUserInfoReqDto.getData().getStage());
					userStageEntity.setInTime(TimeUtil.getBefordayTime(new Date(),
							setUserInfoReqDto.getData().getDay() - 1, setUserInfoReqDto.getData().getDay()));
					userStageEntity.setUuId(UUID_MD5.getUUID());
					userStageEntity.setUserId(appUser.getUuId());
					EntityWrapper<UserStageEntity> wrapper = new EntityWrapper<UserStageEntity>();
					wrapper.eq("user_id", appUser.getUuId());
					// 删除之前的阶段记录
					userStageMapper.delete(wrapper);
					
					userStageMapper.insert(userStageEntity);
				}
				
			}
			if(userStageEntity == null) {
				userStageEntity = new UserStageEntity();
				userStageEntity.setUuId(UUID_MD5.getUUID());
				userStageEntity.setUserId(appUser.getUuId());
				userStageEntity.setCurrentStage(setUserInfoReqDto.getData().getStage());
				userStageEntity.setInTime(TimeUtil.getBefordayTime(new Date(),setUserInfoReqDto.getData().getDay() - 1, setUserInfoReqDto.getData().getDay()));
				
				EntityWrapper<UserStageEntity> wrapper = new EntityWrapper<UserStageEntity>();
				wrapper.eq("user_id", appUser.getUuId());
				// 删除之前的阶段记录
				userStageMapper.delete(wrapper);
				userStageMapper.insert(userStageEntity);
			}

		}

		UserInfo userInfo = userInfoMapper.selectOneByUserId(appUser.getUuId());

		if (userInfo != null) {
			BeanUtils.copyProperties(setUserInfoReqDto.getData(), userInfo);
			userInfo.setStageStartTime(TimeUtil.stringToDate(setUserInfoReqDto.getData().getStageStartTime(), null));
			userInfoMapper.updateByUserId(userInfo);
		} else {
			userInfo = new UserInfo();
			BeanUtils.copyProperties(setUserInfoReqDto.getData(), userInfo);
			userInfo.setUserId(appUser.getUuId());
			userInfo.setUuId(UUID_MD5.getUUID());
			userInfo.setStageStartTime(TimeUtil.stringToDate(setUserInfoReqDto.getData().getStageStartTime(), null));
			userInfoMapper.insertUserInfo(userInfo);
		}

		if (StringUtil.isNotBlank(setUserInfoReqDto.getData().getHeadUrl())) {
			if (!uploadRecordService.updateForSet("belong_id = null",
					new EntityWrapper<UploadRecord>().eq("belong_id", userInfo.getUserId())))
				return new BaseResDto(Status.ERROR.setMessage("修改用户头像数据失败"));
			Wrapper<UploadRecord> wrapper1 = new EntityWrapper<UploadRecord>().eq("url",
					setUserInfoReqDto.getData().getHeadUrl());
			UploadRecord uploadRecord1 = new UploadRecord().setBelongId(appUser.getUuId());
			if (!uploadRecordService.update(uploadRecord1, wrapper1))
				return new BaseResDto(Status.ERROR.setMessage("修改用户头像数据失败"));
		}

		appUser.setNickName(userInfo.getNickName());
		appUserMapper.updateAppUser(appUser);
		RedisUtil.setObject(maiji1RedisTemplate, "maijiToken:" + appUser.getToken(), appUser);
		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public UserInfoResDto getUserInfo(String maijiToken) throws Exception {
		logger.info("UserServiceImpl.getUserInfo,maijiToken is {}", maijiToken);
		// 获得用户id
		AppUser appUser = appUserService.checkToken(maijiToken);

		if (appUser == null) return new UserInfoResDto(Status.TOKENINVALID);

		UserInfo userInfo = userInfoMapper.selectOneByUserId(appUser.getUuId());

		UserInfoResDto userInfoResDto = new UserInfoResDto(Status.SUCCESS);

		UserInfoResDto.UserInfoResData userInfoResData = userInfoResDto.dataInstance();
		if (userInfo == null) {
			return userInfoResDto.setData(userInfoResData);
		}

		BeanUtils.copyProperties(userInfo, userInfoResData);
		userInfoResData.setPhone(appUser.getTel());
		userInfoResData.setCurrentWeight(userInfo.getWeight());
		if(StringUtils.isNotBlank(userInfo.getPayPassword()))userInfoResData.setIsSetPayPassword(true);
		// 已开启麦吉之旅
		if (!StringUtils.isBlank(userInfo.getWeight())) {
			UserStageEntity userStageEntity = userStageMapper.selectOneByUserId(appUser.getUuId());
			if (userStageEntity != null) {
				userInfoResData.setDay(TimeUtil.daysBetween(userStageEntity.getInTime(), new Date()) + 1);
				userInfoResData.setStage(userStageEntity.getCurrentStage());
			}

		}
		// 查询当前体重
		WeightChangeLog weightChangeLog = weightChangeLogMapper.selectOneByUserId(appUser.getUuId());

		if (weightChangeLog != null)
			userInfoResData.setCurrentWeight(weightChangeLog.getCurrentWeight());

		return userInfoResDto.setData(userInfoResData);
	}

	@Override
	public UserInfoResDto getUserInfoWithUserId(BaseInputDto<IdInputDto> inputDto) throws Exception {
		
		IdInputDto idInputDto = inputDto.getData();
		
		if(StringUtils.isBlank(idInputDto.getId())) return new UserInfoResDto(Status.PARAMETERERROR);

		UserInfo userInfo = userInfoMapper.selectOneByUserId(idInputDto.getId());

		UserInfoResDto userInfoResDto = new UserInfoResDto(Status.SUCCESS);

		UserInfoResDto.UserInfoResData userInfoResData = userInfoResDto.dataInstance();
		
		if (userInfo == null) {
			return userInfoResDto.setData(userInfoResData);
		}

		BeanUtils.copyProperties(userInfo, userInfoResData);
		
		if (StringUtils.isNotBlank(inputDto.getData().getToken())&& StringUtils.isNotBlank(inputDto.getData().getId())) {
			// 获得用户id
			AppUser appUser = appUserService.checkToken(inputDto.getData().getToken());
			if (appUser == null || StringUtils.isBlank(appUser.getUuId()))
				return new UserInfoResDto(Status.PARAMETERERROR);
			if (appUser.getUuId().equals(inputDto.getData().getId()))
				userInfoResData.setIsSelf(true);
			userInfoResData.setPhone(appUser.getTel());
		}
		userInfoResData.setCurrentWeight(userInfo.getWeight());
		if(StringUtils.isNotBlank(userInfo.getPayPassword()))userInfoResData.setIsSetPayPassword(true);
		
		// 已开启麦吉之旅
		if (!StringUtils.isBlank(userInfo.getWeight())) {
			UserStageEntity userStageEntity = userStageMapper.selectOneByUserId(idInputDto.getId());
			if (userStageEntity != null) {
				userInfoResData.setDay(TimeUtil.daysBetween(userStageEntity.getInTime(), new Date()) + 1);
				userInfoResData.setStage(userStageEntity.getCurrentStage());
			}

		}
		// 查询当前体重
		WeightChangeLog weightChangeLog = weightChangeLogMapper.selectOneByUserId(idInputDto.getId());

		if (weightChangeLog != null)
			userInfoResData.setCurrentWeight(weightChangeLog.getCurrentWeight());

		userInfoResDto.setData(userInfoResData);

		return userInfoResDto;
	}

	@Override
	public BaseDataResDto<RecordWeightResData> recordWeight(RecordWeightReqDto recordWeightReqDto) throws Exception {
		logger.info("UserServiceImpl.getUserInfo,recordWeight ,recordWeightReqDto is {}",
				JSON.toJSONString(recordWeightReqDto));

		// 获得用户id
		AppUser appUser = appUserService.checkToken(recordWeightReqDto.getData().getMaijiToken());

		if (appUser == null) {
			logger.info("UserServiceImpl.getUserInfo,recordWeight ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<RecordWeightResData>(Status.PARAMETERERROR, "token 无效 ");
		}
		if (StringUtils.isBlank(recordWeightReqDto.getData().getCurrentWeight()))
			return new BaseDataResDto(Status.PARAMETERERROR, "体重传参为空");
		Date date = null;
		if (StringUtils.isBlank(recordWeightReqDto.getData().getRecordTime())) {
			date = TimeUtil.stringToDate(TimeUtil.date2String(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd");

		} else {
			date = TimeUtil.stringToDate(recordWeightReqDto.getData().getRecordTime(), "yyyy-MM-dd");
		}

		WeightChangeLog weightChangeLog = weightChangeLogMapper.getWeightChangeLogByuserIdAndTime(date,
				appUser.getUuId());
		// 当天有记录就更新否则添加
		if (weightChangeLog != null) {
			Double losweight = Arith.subtract(2, Double.parseDouble(weightChangeLog.getCurrentWeight()),
					Double.parseDouble(recordWeightReqDto.getData().getCurrentWeight()));
			weightChangeLog.setCurrentWeight(recordWeightReqDto.getData().getCurrentWeight());
			weightChangeLogMapper.updateByPrimaryKey(weightChangeLog);
			return new BaseDataResDto<RecordWeightResData>(Status.SUCCESS).setData(new RecordWeightResData().setLoseWeight(losweight));
		}
		weightChangeLog = new WeightChangeLog();
		weightChangeLog.setUuId(UUID_MD5.getUUID());
		weightChangeLog.setUserId(appUser.getUuId());
		weightChangeLog.setInTime(new Date());
		weightChangeLog.setRecordTime(date);
		BeanUtils.copyProperties(recordWeightReqDto.getData(), weightChangeLog);

		weightChangeLogMapper.insert(weightChangeLog);

		BaseDataResDto<RecordWeightResData> baseDataResDto = new BaseDataResDto<RecordWeightResData>(Status.SUCCESS);

		// 获取今天之前最新一次记录
		WeightChangeLog beforWeightChangeLog = weightChangeLogMapper
				.getNewWeightChangeLogByuserIdAndTime(TimeUtil.getBefordayTime(new Date(), 1, 1), appUser.getUuId());
		if (beforWeightChangeLog == null) {
			beforWeightChangeLog = new WeightChangeLog();
			UserInfo userInfo = userInfoMapper.selectOneByUserId(appUser.getUuId());
			if (StringUtils.isBlank(userInfo.getWeight()))
				return baseDataResDto;
			beforWeightChangeLog.setCurrentWeight(userInfo.getWeight());
		}
		Double reduceWeight = Arith.subtract(2, Double.parseDouble(beforWeightChangeLog.getCurrentWeight()),
				Double.parseDouble(recordWeightReqDto.getData().getCurrentWeight()));
		
		// 判断是不是记录当天体重
		if (date.getTime() < TimeUtil.stringToDate(TimeUtil.date2String(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd")
				.getTime()) {
			return baseDataResDto.setData(new RecordWeightResData().setLoseWeight(reduceWeight));
		}
		
		Double baseFund = getBaseFund(reduceWeight);
		// 判断是否能获得基础减肥基金
		if (baseFund != null) {

			ShareWeightHelpRule shareWeightHelpRule = mongoTemplate.findOne(
					new Query(Criteria.where("type")
							.is(CommonIntValueEnum.MONGO_RULE_TYPE_REDUCE_WEIGHT_HELP_FUND.getValue())),
					ShareWeightHelpRule.class, ShareWeightRuleEntity.TABLE_NAME);
			// 已经获得减肥基金，修改账户，添加流水,记录获取减肥基金记录
			ReduceWeightFundLogEntity reduceWeightFundLogEntity = new ReduceWeightFundLogEntity();
			reduceWeightFundLogEntity.setUuId(UUID_MD5.getUUID());
			reduceWeightFundLogEntity.setUserId(appUser.getUuId());
			reduceWeightFundLogEntity.setWeightChangeLogId(weightChangeLog.getUuId());
			reduceWeightFundLogEntity.setMoney(baseFund);
			reduceWeightFundLogEntity.setInTime(new Date());
			reduceWeightFundLogEntity.setLoseWeight(reduceWeight);

			//long endTime = (long) (System.currentTimeMillis() + shareWeightHelpRule.getTime() * 60 * 60 * 1000);
			Date endTime = TimeUtil.stringToDate(TimeUtil.date2String(new Date(), "yyyy-MM-dd")+" "+shareWeightHelpRule.getTime() , "yyyy-MM-dd HH:mm:ss");
			reduceWeightFundLogEntity.setEndTime(endTime);
			reduceWeightFundLogMapper.insert(reduceWeightFundLogEntity);
			// 注释说明：此处改为用户领取
//			DistributeFundReqDto distributeFundReqDto = new DistributeFundReqDto();
//			DistributeFundReqData distributeFundReqData = distributeFundReqDto.dataInstance();
//			distributeFundReqData.setFund(baseFund);
//			distributeFundReqData.setRelevantId(reduceWeightFundLogEntity.getUuId());
//			distributeFundReqData.setRemark(FlowTypeEnum.BASE_LOSE_WEIGHT_FUND);
//
//			distributeFundReqDto.setData(distributeFundReqData);
//			// 远程调用分发积分接口
//			Boolean bool = integralService.distributeFundByToken(distributeFundReqDto,
//					recordWeightReqDto.getData().getMaijiToken());
//			if (!bool) {
//				throw new Exception("抛出结算异常");
//			}
			RecordWeightResData resData = new RecordWeightResData();
			BeanUtils.copyProperties(reduceWeightFundLogEntity, resData);
			resData.setUrl(webUrl + "/pages/loseWeight/loseWeight?uuId=" + resData.getUuId());

			baseDataResDto.setData(resData);
			return baseDataResDto;
		}

		return baseDataResDto.setData(new RecordWeightResData().setLoseWeight(reduceWeight));
	}

	// 判断是否能获取减肥基金的方法
	private Double getBaseFund(Double weigtht) {
		// 获取基础减肥基金的规则
		ShareWeightRuleEntity shareWeightRuleEntity = mongoTemplate.findOne(
				new Query(Criteria.where("type")
						.is(CommonIntValueEnum.MONGO_RULE_TYPE_REDUCE_WEIGHT_BASE_FUND.getValue())),
				ShareWeightRuleEntity.class, ShareWeightRuleEntity.TABLE_NAME);
		
		if(shareWeightRuleEntity.getIsOpen() == null || !shareWeightRuleEntity.getIsOpen()) return null;

		if (weigtht < shareWeightRuleEntity.getMinWeight() || weigtht > shareWeightRuleEntity.getMaxWeight()) {
			return null;
		}
		Integer sum = reduceWeightFundLogMapper.getTodaySum(TimeUtil.getZeroTime(new Date()));

		if (sum >= shareWeightRuleEntity.getPeopleNum()) {
			return null;
		}

		if (Math.random() > shareWeightRuleEntity.getProbability()) {
			return null;
		}
		// 随机获取得到的减肥基金
//		double baseFund = Arith.getRandomNum(shareWeightRuleEntity.getMinBasicsFund(),
//				shareWeightRuleEntity.getMaxBasicsFund());
		
		//修改为
		double baseFund = Arith.multiplys(2, weigtht,shareWeightRuleEntity.getBaseFund());

		return baseFund;
	}

	@Override
	public WeightChangeLogListResDto getWeightChangeLogList(String maijiToken) {
		logger.info("UserServiceImpl.getWeightChangeLogList ,maijiToken is {}", maijiToken);
		// 获得用户id
		AppUser appUser = appUserService.checkToken(maijiToken);

		if (appUser == null) {
			logger.info("UserServiceImpl.getWeightChangeLogList,recordWeight ,appUser is {}",
					JSON.toJSONString(appUser));
			BaseResDto.baseResDto(Status.PARAMETERERROR, "token 无效 ");
		}

		List<WeightChangeLog> list = weightChangeLogMapper.getWeightChangeLogListByUserId(appUser.getUuId());

		WeightChangeLogListResDto weightChangeLogListResDto = new WeightChangeLogListResDto(Status.SUCCESS);

		List<WeightChangeLogResData> WeightChangeLogListDataList = new ArrayList<WeightChangeLogResData>();

		for (WeightChangeLog weightChangeLog : list) {

			WeightChangeLogResData weightChangeLogListData = weightChangeLogListResDto.tDataInstance();
			BeanUtils.copyProperties(weightChangeLog, weightChangeLogListData);

			WeightChangeLogListDataList.add(weightChangeLogListData);
		}
		weightChangeLogListResDto.setData(WeightChangeLogListDataList);

		return weightChangeLogListResDto;
	}

	@Override
	public BaseResDto updateUserInfo(UpdateUserInfoReqDto updateUserInfoReqDto) throws Exception {
		logger.info("UserServiceImpl.updateUserInfo ,parma is {}", JSON.toJSONString(updateUserInfoReqDto));
		// 获得用户id
		AppUser appUser = appUserService.checkToken(updateUserInfoReqDto.getData().getMaijiToken());

		if (appUser == null) {
			logger.info("UserServiceImpl.updateUserInfo,appUser is {}", JSON.toJSONString(appUser));
			return BaseResDto.baseResDto(Status.PARAMETERERROR, "token 无效 ");
		}

		UserInfo userInfo = userInfoMapper.selectOneByUserId(appUser.getUuId());

		if (userInfo == null) {
			logger.info("UserServiceImpl.updateUserInfo,userInfo is {}", JSON.toJSONString(userInfo));
			return BaseResDto.baseResDto(Status.PARAMETERERROR, "token 无效 ");
		}

		if (StringUtil.isNotBlank(updateUserInfoReqDto.getData().getHeadUrl())) {
			uploadRecordService.updateForSet("belong_id = null",
					new EntityWrapper<UploadRecord>().eq("belong_id", userInfo.getUserId()).eq("url",userInfo.getHeadUrl()));
			Wrapper<UploadRecord> wrapperUpd = new EntityWrapper<UploadRecord>().eq("url",
					updateUserInfoReqDto.getData().getHeadUrl());
			UploadRecord uploadRecord = new UploadRecord().setBelongId(appUser.getUuId());
			if (!uploadRecordService.update(uploadRecord, wrapperUpd))
				return new BaseResDto(Status.ERROR.setMessage("修改用户头像数据失败"));
		}
		
		if (StringUtil.isNotBlank(updateUserInfoReqDto.getData().getMainPageUrl())) {
			uploadRecordService.updateForSet("belong_id = null",
					new EntityWrapper<UploadRecord>().eq("belong_id", userInfo.getUserId()).eq("url",userInfo.getMainPageUrl()));
			Wrapper<UploadRecord> wrapperUpd = new EntityWrapper<UploadRecord>().eq("url",
					updateUserInfoReqDto.getData().getMainPageUrl());
			UploadRecord uploadRecord = new UploadRecord().setBelongId(appUser.getUuId());
			if (!uploadRecordService.update(uploadRecord, wrapperUpd))
				return new BaseResDto(Status.ERROR.setMessage("修改个人主页图片失败"));
		}

		BeanUtils.copyProperties(updateUserInfoReqDto.getData(), userInfo);
		userInfoMapper.updateByUserId(userInfo);

		UserStageEntity userStageEntity = userStageMapper.selectOneByUserId(appUser.getUuId());
		if (userStageEntity != null ) {
			Integer days = TimeUtil.daysBetween(userStageEntity.getInTime(), new Date()) + 1;
			if(updateUserInfoReqDto.getData().getDay() == null) updateUserInfoReqDto.getData().setDay(days);
			if(updateUserInfoReqDto.getData().getStage() == null)updateUserInfoReqDto.getData().setStage(userStageEntity.getCurrentStage());
			if (!(days.equals(updateUserInfoReqDto.getData().getDay())
					&& updateUserInfoReqDto.getData().getStage() == userStageEntity.getCurrentStage())) {
				userStageEntity.setCurrentStage(updateUserInfoReqDto.getData().getStage());
				userStageEntity.setInTime(TimeUtil.getBefordayTime(new Date(), updateUserInfoReqDto.getData().getDay()-1,
						updateUserInfoReqDto.getData().getDay()));
				userStageEntity.setUuId(UUID_MD5.getUUID());
				userStageEntity.setUserId(appUser.getUuId());
				EntityWrapper<UserStageEntity> wrapper = new EntityWrapper<UserStageEntity>();
				wrapper.eq("user_id", appUser.getUuId());
				// 删除之前的阶段记录
				userStageMapper.delete(wrapper);
				
				userStageMapper.insert(userStageEntity);
			}
		}

		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseDataResDto<UserSignListResData> userSignIn(String maijiToken) throws Exception {
		logger.info("UserServiceImpl.userSignIn ,maijiToken is {}", maijiToken);
		// 获得用户id
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.userSignIn,recordWeight ,appUser is {}", JSON.toJSONString(appUser));
			BaseResDto.baseResDto(Status.PARAMETERERROR, "token 无效 ");
		}

		UserSignInEntity userSignInEntity = userSignInMapper.selectOneByUserId(appUser.getUuId());
		int day = 1; // 默认第一天签到
		if (userSignInEntity != null) {
			String nowTime = TimeUtil.date2String(new Date(), "yyyy-MM-dd");
			String signInTime = TimeUtil.date2String(userSignInEntity.getInTime(), "yyyy-MM-dd");

			int days = (int) ((TimeUtil.stringToDate(nowTime, "yyyy-MM-dd").getTime()
					- TimeUtil.stringToDate(signInTime, "yyyy-MM-dd").getTime()) / (24 * 60 * 60 * 1000));

			if (days < 2 && days >= 1) {
				day = userSignInEntity.getDay() + 1;
			}

			if (0 == days) {
				logger.info("UserServiceImpl.userSignIn ,maijiToken is {},重复签到", maijiToken);
				return new BaseDataResDto<UserSignListResData>(Status.PARAMETERERROR, "已经签到 ");
			}

		}

		SignInDeployEntity signInDeployEntity = signInDeployMapper.selectOneByDay(day);

		if (signInDeployEntity == null) {
			signInDeployEntity = signInDeployMapper.selectOneByDayMax();
		}

		String uuId = UUID_MD5.getUUID();

		// 添加签到记录
		UserSignInEntity userSignIn = new UserSignInEntity();
		userSignIn.setUuId(uuId);
		userSignIn.setUserId(appUser.getUuId());
		userSignIn.setIntegral(signInDeployEntity.getIntegral());
		userSignIn.setDay(day);
		userSignIn.setInTime(new Date());

		userSignInMapper.insert(userSignIn);

		DistributeIntegralReqDto distributeIntegralReqDto = new DistributeIntegralReqDto();
		DistributeIntegralReqData distributeIntegralReqData = distributeIntegralReqDto.dataInstance();

		distributeIntegralReqData.setIntegral(signInDeployEntity.getIntegral());
		distributeIntegralReqData.setRemark(FlowTypeEnum.SIGN_IN);
		distributeIntegralReqData.setRelevantId(uuId);
		distributeIntegralReqDto.setData(distributeIntegralReqData);

		Boolean bool = integralService.distributeIntegralByToken(distributeIntegralReqDto, maijiToken);

		if (!bool) {
			logger.info("UserServiceImpl.userSignIn ,maijiToken is {},签到调用添加积分接口异常 返回值 {}", maijiToken, bool);
			throw new Exception("签到调取积分结算异常");
		}
		UserSignListResData responseData = new UserSignListResData();
		BeanUtils.copyProperties(userSignIn, responseData);
		return new BaseDataResDto<UserSignListResData>(Status.SUCCESS).setData(responseData);
	}

	@SuppressWarnings("unused")
	@Override
	public UserSignListResDto getUserSignIn(String maijiToken) throws Exception {
		logger.info("UserServiceImpl.getUserSignIn ,maijiToken is {}", maijiToken);
		// 获得用户id
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.getUserSignIn ,appUser is {}", JSON.toJSONString(appUser));
			return new UserSignListResDto(Status.ERROR);
		}
		UserSignInEntity userSignInEntity = userSignInMapper.selectOneByUserId(appUser.getUuId());
		SignInDeployEntity signInDeployEntity = signInDeployMapper.selectOneByDayMax();
		UserSignListResDto userSignListResDto = new UserSignListResDto(Status.SUCCESS);
		List<UserSignListResData> listUserSignListResData = new ArrayList<UserSignListResData>();
		if (userSignInEntity == null) {
			userSignListResDto.setData(listUserSignListResData);
			return userSignListResDto;
		}
		String nowTime = TimeUtil.date2String(new Date(), "yyyy-MM-dd");
		String signInTime = TimeUtil.date2String(userSignInEntity.getInTime(), "yyyy-MM-dd");
		int days = (int) ((TimeUtil.stringToDate(nowTime, "yyyy-MM-dd").getTime()
				- TimeUtil.stringToDate(signInTime, "yyyy-MM-dd").getTime()) / (24 * 60 * 60 * 1000));

		if (days >= 2) {
			userSignListResDto.setData(listUserSignListResData);
			return userSignListResDto;
		}

		Integer limit = 0;
		// 连续签到天数不在一个周期之内
		if (userSignInEntity.getDay() >= signInDeployEntity.getDay()) {
			limit = signInDeployEntity.getDay();
		} else {
			// 连续签到天数超过一个周期取得数据条数为周期数-1
			limit = userSignInEntity.getDay();
		}

		List<UserSignInEntity> listUserSignInEntity = userSignInMapper.selectListByUserId(appUser.getUuId(), limit);

		for (UserSignInEntity userSignIn : listUserSignInEntity) {
			UserSignListResData userSignListResData = new UserSignListResData();
			BeanUtils.copyProperties(userSignIn, userSignListResData);
			listUserSignListResData.add(userSignListResData);
		}
		userSignListResDto.setData(listUserSignListResData);

		return userSignListResDto;
	}

	@Override
	public SignInDeployAllResDto getSignInDeployAll() {

		List<SignInDeployEntity> list = signInDeployMapper.selectAll();
		List<SignInDeployAllResData> listSignInDeployAllResData = new ArrayList<SignInDeployAllResData>();

		for (SignInDeployEntity signInDeployEntity : list) {
			SignInDeployAllResData SignInDeployAllResData = new SignInDeployAllResData();
			BeanUtils.copyProperties(signInDeployEntity, SignInDeployAllResData);
			listSignInDeployAllResData.add(SignInDeployAllResData);
		}
		SignInDeployAllResDto signInDeployAllResDto = new SignInDeployAllResDto(Status.SUCCESS);

		signInDeployAllResDto.setData(listSignInDeployAllResData);

		return signInDeployAllResDto;
	}

	@Override
	public ForwardingRecordsListResDto getforwardingRecordsList(BaseDataReqDto param, String maijiToken) {
		logger.info("UserServiceImpl.forwardingRecords ,param is {},maijiToken is {}", JSON.toJSONString(param),
				maijiToken);
		// 获得用户id
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.forwardingRecords ,appUser is {}", JSON.toJSONString(appUser));
			return new ForwardingRecordsListResDto(Status.ERROR);
		}
		Integer start = (param.getMetaData().getPage() - 1) * param.getMetaData().getSize();
		List<ForwardingRecordsEntity> list = forwardingRecordsMapper
				.selectListForwardingRecordsByUserId(appUser.getUuId(), start, param.getMetaData().getSize());
		List<ForwardingRecordsListResData> data = new ArrayList<ForwardingRecordsListResData>();

		for (ForwardingRecordsEntity forwardingRecordsEntity : list) {
			ForwardingRecordsListResData forwardingRecordsListResData = new ForwardingRecordsListResData();
			BeanUtils.copyProperties(forwardingRecordsEntity, forwardingRecordsListResData);
			Integer count = forwardingRecordshelpMapper
					.selectCountByForwardingRecordsId(forwardingRecordsEntity.getUuId());
			forwardingRecordsListResData.setNum(count);
			data.add(forwardingRecordsListResData);
		}
		ForwardingRecordsListResDto forwardingRecordsListResDto = new ForwardingRecordsListResDto(Status.SUCCESS);
		forwardingRecordsListResDto.setData(data);
		return forwardingRecordsListResDto;
	}

	@Override
	public BaseResDto forwardingRecordsHelp(ForwardingRecordsHelpReqDto param) {
		logger.info("UserServiceImpl.forwardingRecordsHelp ,param is {}", JSON.toJSONString(param));
		ForwardingRecordsHelpEntity forwardingRecordsHelpEntity = forwardingRecordshelpMapper
				.selectOneByOpenId(param.getData().getForwardingRecordsId(), param.getData().getOpenId());
		if (forwardingRecordsHelpEntity != null) {
			return BaseResDto.baseResDto(Status.SUCCESS, "已经助力");
		}

		forwardingRecordsHelpEntity = new ForwardingRecordsHelpEntity();
		BeanUtils.copyProperties(param.getData(), forwardingRecordsHelpEntity);
		forwardingRecordsHelpEntity.setUuId(UUID_MD5.getUUID());
		forwardingRecordsHelpEntity.setInTime(new Date());

		forwardingRecordshelpMapper.insert(forwardingRecordsHelpEntity);
		return BaseResDto.baseResDto(Status.SUCCESS, "助力成功");
	}

	@Override
	public BaseResDto forwardingRecords(ForwardingRecordsReqDto param, String maijiToken) {
		logger.info("UserServiceImpl.forwardingRecords ,param is {},maijiToken is {}", JSON.toJSONString(param),
				maijiToken);
		// 获得用户id
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.forwardingRecords ,appUser is {}", JSON.toJSONString(appUser));
			return new ForwardingRecordsListResDto(Status.ERROR);
		}

		ForwardingRecordsEntity forwardingRecordsEntity = new ForwardingRecordsEntity();
		BeanUtils.copyProperties(param.getData(), forwardingRecordsEntity);

		forwardingRecordsEntity.setUuId(UUID_MD5.getUUID());
		forwardingRecordsEntity.setUserId(appUser.getUuId());
		forwardingRecordsEntity.setInTime(new Date());

		forwardingRecordsMapper.insert(forwardingRecordsEntity);
		return BaseResDto.baseResDto(Status.SUCCESS, "转发成功");
	}

	@Override
	public DistributionSumResDto getDistributionSum(DistributionLogListReqDto param, String maijiToken) {
		logger.info("UserServiceImpl.getDistributionSum ,param is {},maijiToken is {}", JSON.toJSONString(param),
				maijiToken);
		// 获得用户id
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.getDistributionSum ,appUser is {}", JSON.toJSONString(appUser));
			return new DistributionSumResDto(Status.ERROR, "token无效");
		}
		// 获得此用户今日新增的一级用户
		List<DistributionUserListResData> listTodayAppUser = appUserMapper.selectUserByPid(appUser.getUuId(),
				TimeUtil.getZeroTime(new Date()));
		// 获得此用户所有的一级用户
		List<DistributionUserListResData> listAppUser = appUserMapper.selectUserByPid(appUser.getUuId(), null);

		DistributionSumResDto distributionSumResDto = new DistributionSumResDto(Status.SUCCESS, "请求成功");

		DistributionSumResData distributionSumResData = distributionSumResDto.dataInstance();

		// 一级用户统计
		if (CommonIntValueEnum.DISTRIBUTION_LOG_LEVEL_ONE.getValue().equals(param.getData().getLevel())) {
			distributionSumResData.setTodayAddNum(listTodayAppUser.size());
			distributionSumResData.setSumUser(listAppUser.size());
			// 远程调用购物模块
			Double sumMoney = integralService.getDistributionSumMoney(param, maijiToken);
			distributionSumResData.setSumMoney(sumMoney);
		}
		int todayAddNum = 0;
		int sumUser = 0;
		// 二级用户
		if (CommonIntValueEnum.DISTRIBUTION_LOG_LEVEL_TWO.getValue().equals(param.getData().getLevel())) {
			// 今日新增二级用户
			for (DistributionUserListResData appUserOne : listTodayAppUser) {
				List<DistributionUserListResData> newlistTodayAppUser = appUserMapper
						.selectUserByPid(appUserOne.getUuId(), TimeUtil.getZeroTime(new Date()));
				todayAddNum += newlistTodayAppUser.size();
			}
			// 所有的二级用户
			for (DistributionUserListResData appUserOne : listAppUser) {
				List<DistributionUserListResData> newlistAppUser = appUserMapper.selectUserByPid(appUserOne.getUuId(),
						null);
				sumUser += newlistAppUser.size();
			}

			distributionSumResData.setTodayAddNum(todayAddNum);
			distributionSumResData.setSumUser(sumUser);
			// 远程调用购物模块
			Double sumMoney = integralService.getDistributionSumMoney(param, maijiToken);
			distributionSumResData.setSumMoney(sumMoney);
		}
		distributionSumResDto.setData(distributionSumResData);
		return distributionSumResDto;
	}

	@Override
	public DistributionUserListResDto getDistributionUserList(DistributionLogListReqDto param, String maijiToken) {
		logger.info("UserServiceImpl.getDistributionUserList ,param is {},maijiToken is {}", JSON.toJSONString(param),
				maijiToken);
		// 获得用户id
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.getDistributionSum ,appUser is {}", JSON.toJSONString(appUser));
			return new DistributionUserListResDto(Status.ERROR, "token无效");
		}
		Integer start = (param.getPage() - 1) * param.getSize();
		// 获得此用户今日新增的一级用户
		List<DistributionUserListResData> listTodayAppUser = appUserMapper.selectListUserByPid(appUser.getUuId(),
				TimeUtil.getZeroTime(new Date()), start, param.getSize());
		// 获得此用户所有的一级用户
		List<DistributionUserListResData> listAppUser = appUserMapper.selectListUserByPid(appUser.getUuId(), null,
				start, param.getSize());

		List<DistributionUserListResData> data = new ArrayList<DistributionUserListResData>();
		// 一级用户统计
		if (CommonIntValueEnum.DISTRIBUTION_LOG_LEVEL_ONE.getValue().equals(param.getData().getLevel())) {
			//
			if (param.getData().getType() == 1) {
				data.addAll(listAppUser);
			}

			if (param.getData().getType() == 2) {
				data.addAll(listTodayAppUser);
			}

		}

		if (CommonIntValueEnum.DISTRIBUTION_LOG_LEVEL_TWO.getValue().equals(param.getData().getLevel())) {
			for (DistributionUserListResData twoAppUser : listAppUser) {
				// 获得此用户今日新增的二级用户
				List<DistributionUserListResData> listTodayAppUserTwo = appUserMapper.selectListUserByPid(
						twoAppUser.getUuId(), TimeUtil.getZeroTime(new Date()), start, param.getSize());
				// 获得此用户所有的二级用户
				List<DistributionUserListResData> listAppUserTwo = appUserMapper
						.selectListUserByPid(twoAppUser.getUuId(), null, start, param.getSize());
				//
				if (param.getData().getType() == 1) {
					data.addAll(listAppUserTwo);
				}
				if (param.getData().getType() == 2) {
					data.addAll(listTodayAppUserTwo);
				}

			}

		}
		DistributionUserListResDto distributionUserListResDto = new DistributionUserListResDto(Status.SUCCESS, "请求成功");
		distributionUserListResDto.setData(data);
		ReqMetaData reqMetaData = new ReqMetaData();
		reqMetaData.setPage(param.getPage());
		reqMetaData.setSize(param.getSize());
		return distributionUserListResDto;
	}

	@Override
	public BaseResDto recordStage(BaseDataReqDto<RecordStageReqDataDto> param, String maijiToken) throws Exception {
		logger.info("UserServiceImpl.recordStage ,param is {},maijiToken is {}", JSON.toJSONString(param), maijiToken);
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.recordStage ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseResDto(Status.ERROR, "token无效");
		}
		Integer stage = param.getData().getStage();
		if (stage == null) {
			logger.info("UserServiceImpl.recordStage ,stage is {}", stage);
			return new BaseResDto(Status.PARAMETERERROR, "阶段值为空");
		}
		UserStageEntity userStageEntity = userStageMapper.selectOneByUserId(appUser.getUuId());
		if (userStageEntity != null) {
			if(param.getData().getDay() == null)param.getData().setDay(1);
			Integer days = TimeUtil.daysBetween(userStageEntity.getInTime(), new Date()) + 1;
			if (!(days.equals(param.getData().getDay())
					&& param.getData().getStage() == userStageEntity.getCurrentStage())) {
				userStageEntity.setCurrentStage(param.getData().getStage());
				userStageEntity.setInTime(
						TimeUtil.getBefordayTime(new Date(), param.getData().getDay()-1, param.getData().getDay()));
				userStageEntity.setUuId(UUID_MD5.getUUID());
				userStageEntity.setUserId(appUser.getUuId());
				EntityWrapper<UserStageEntity> wrapper = new EntityWrapper<UserStageEntity>();
				wrapper.eq("user_id", appUser.getUuId());
				// 删除之前的阶段记录
				userStageMapper.delete(wrapper);
				
				userStageMapper.insert(userStageEntity);
			}
		}else{
			UserStageEntity userStageEntity2 = new UserStageEntity();
			userStageEntity2.setUuId(UUID_MD5.getUUID());
			userStageEntity2.setUserId(appUser.getUuId());
			if(param.getData().getDay() == null)param.getData().setDay(1);
			userStageEntity2.setCurrentStage(param.getData().getStage());
			userStageEntity2.setInTime(
					TimeUtil.getBefordayTime(new Date(), param.getData().getDay() - 1, param.getData().getDay()));
			userStageMapper.insert(userStageEntity2);
		}

		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseDataResDto<List<WeightChangeLogResData>> getKetonuria(BaseDataReqDto<GetKetonuriaResData> param,
			String maijiToken) throws Exception {
		logger.info("UserServiceImpl.getKetonuria ,maijiToken is {}", maijiToken);
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.getKetonuria ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<List<WeightChangeLogResData>>(Status.ERROR, "token无效");
		}

		List<KetonuriaChangeLog> ketonuriaChangeLogList = ketonuriaChangeLogMapper.getListRecordKetonuria(
				appUser.getUuId(), param.getData().getStartTime(), param.getData().getEndTime());

		BaseDataResDto<List<WeightChangeLogResData>> responseData = new BaseDataResDto<List<WeightChangeLogResData>>(
				Status.SUCCESS);
		List<WeightChangeLogResData> listWeightChangeLogListData = new ArrayList<WeightChangeLogResData>();
		for (KetonuriaChangeLog ketonuriaChangeLog : ketonuriaChangeLogList) {
			WeightChangeLogResData weightChangeLogListData = new WeightChangeLogResData();
			BeanUtils.copyProperties(ketonuriaChangeLog, weightChangeLogListData);
			listWeightChangeLogListData.add(weightChangeLogListData);
		}
		responseData.setData(listWeightChangeLogListData);

		return responseData;
	}

	@Override
	public BaseResDto recordKetonuria(BaseDataReqDto<String> param, String maijiToken) {
		logger.info("UserServiceImpl.getKetonuria ,maijiToken is {}", maijiToken);
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.getKetonuria ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseResDto(Status.ERROR, "token无效");
		}

		// 判断今天是否已经记录
		KetonuriaChangeLog ketonuriaChangeLog = ketonuriaChangeLogMapper.getLastRecordKetonuria(appUser.getUuId());

		if (ketonuriaChangeLog != null
				&& ketonuriaChangeLog.getInTime().getTime() > TimeUtil.getZeroTime(new Date()).getTime()) {
			// 已经记录
			ketonuriaChangeLog.setKetonuria(param.getData());
			ketonuriaChangeLogMapper.updateById(ketonuriaChangeLog);
			return new BaseResDto(Status.SUCCESS);
		}
		ketonuriaChangeLog = new KetonuriaChangeLog();
		ketonuriaChangeLog.setUuId(UUID_MD5.getUUID());
		ketonuriaChangeLog.setUserId(appUser.getUuId());
		ketonuriaChangeLog.setKetonuria(param.getData());
		ketonuriaChangeLog.setInTime(new Date());

		ketonuriaChangeLogMapper.insert(ketonuriaChangeLog);

		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseDataResDto<AppUser> getAppUer(BaseDataReqDto<String> param) {

		AppUser appUser = appUserMapper.selectById(param.getData());
		BaseDataResDto<AppUser> baseDataResDto = new BaseDataResDto<AppUser>(Status.SUCCESS);
		baseDataResDto.setData(appUser);

		return baseDataResDto;
	}

	@Override
	public BaseMetaResDto<List<UserInfoResData>> findAllMaijiUsers (MaijiUserFindAllReqData data, ReqMetaData metaData) {
		EntityWrapper<UserInfo> entityWrapper = new EntityWrapper<>();
        List<AppUser> appUsers = Lists.newArrayList();
		if (StringUtil.isNotBlank(data.getTel())) {
            appUsers = appUserService.selectList(new EntityWrapper<AppUser>().like("tel", data.getTel()));
            List<String> userIds = appUsers.parallelStream().map(AppUser::getUuId).collect(Collectors.toList());
            if (userIds.size() > 0) entityWrapper.in("user_id", userIds);
        }
		if (StringUtil.isNotBlank(data.getNickName()))
			entityWrapper.like("nick_name", data.getNickName());
		if (data.getRegDates() != null) {
            List<Date> regDates = data.getRegDates();
            if (regDates.size() > 0) entityWrapper.ge("reg_date", regDates.get(0));
            if (regDates.size() > 1) entityWrapper.le("reg_date", regDates.get(1));
        }
		entityWrapper.andNew().isNull("id_card").or().ne("id_card", "123456");
		entityWrapper.orderBy(data.getOrderBy(), data.getOrderType().equals("asc"));
		Page<UserInfo> page = selectPage(new Page<>(metaData.getPage(), metaData.getSize()), entityWrapper);
        List<String> userIds = page.getRecords().parallelStream().map(UserInfo::getUserId).collect(Collectors.toList());
        List<UserInfoResData> userInfoResList = Lists.newArrayList();
        if (userIds.size() > 0) {
            if (appUsers.size() == 0) appUsers = appUserService.selectBatchIds(userIds);
            userInfoResList= BaseService.dealWithOneToOne(page.getRecords(), "getUserId",
                    UserInfoResData.class, "setAppUser", appUsers, "getUuId", AppUserResData.class);
            if (BooleanUtils.isFalse(data.getCapital())) {
                Wrapper<WeightChangeLog> weightChangeLogWrapper = new EntityWrapper<WeightChangeLog>()
                        .in("user_id", userIds).orderBy("record_time", false);
                Map<String, List<WeightChangeLog>> weightMap = weightChangeLogService.selectList(weightChangeLogWrapper)
                        .parallelStream().collect(Collectors.groupingBy(WeightChangeLog::getUserId));
                userInfoResList = userInfoResList.parallelStream().map(userInfo -> {
                    List<WeightChangeLog> weightChangeLogs = weightMap.get(userInfo.getUserId());
                    if (weightChangeLogs != null) {
                        userInfo.setWcls(weightChangeLogs);
                        Optional<WeightChangeLog> optional = weightChangeLogs.parallelStream().findFirst();
                        if (optional.isPresent())
                            userInfo.setCurrentWeight(optional.get().getCurrentWeight());
                    }
                    return userInfo;
                }).collect(Collectors.toList());
            }
            if (BooleanUtils.isTrue(data.getCapital())) {
                List<CapitalMain> capitalMains = capitalMainMService.findAllCapitalMains(userIds);
                userInfoResList = BaseService.dealWithOneToOne(userInfoResList, "getUserId",
                        UserInfoResData.class, "setCapitalMain", capitalMains, "getUserId", CapitalMain.class);
            }
        }
		ResMetaData resMetaData = new ResMetaData(page.getCurrent(), page.getSize(), page.getTotal());
		return new BaseMetaResDto<List<UserInfoResData>>(Status.SUCCESS).setData(userInfoResList).setResMetaData(resMetaData);
	}

	@Override
	public BaseDataResDto<UserInfoResData> findUserInfo(String maijiToken) {
		AppUser appUser = RedisUtil.getAppUserByRedis(maiji1RedisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, appUserService);
		EntityWrapper<UserInfo> entityWrapper = new EntityWrapper<>();
		entityWrapper.eq("user_id", appUser.getUuId());
		UserInfo userInfo = selectOne(entityWrapper);
		UserInfoResData userInfoResData = new UserInfoResData();
		BeanUtils.copyProperties(userInfo, userInfoResData);
		return new BaseDataResDto<UserInfoResData>(Status.SUCCESS).setData(userInfoResData);
	}

	@Override
	public BaseDataResDto<IsHaveReduceWeightFundLogResData> isHaveReduceWeightFundLog(String maijiToken)
			throws Exception {
		logger.info("UserServiceImpl.isHaveReduceWeightFundLog ,maijiToken is {}", maijiToken);
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.isHaveReduceWeightFundLog ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<IsHaveReduceWeightFundLogResData>(Status.ERROR, "token无效");
		}
		String nowTime = TimeUtil.date2String(new Date(), "yyyy-MM-dd");
		ReduceWeightFundLogEntity reduceWeightFundLogEntity = reduceWeightFundLogMapper.selectOneByTime(nowTime,
				appUser.getUuId());
		BaseDataResDto<IsHaveReduceWeightFundLogResData> response = new BaseDataResDto<IsHaveReduceWeightFundLogResData>(
				Status.SUCCESS);

		IsHaveReduceWeightFundLogResData responseData = new IsHaveReduceWeightFundLogResData();
		if (reduceWeightFundLogEntity != null) {
			responseData.setUuId(reduceWeightFundLogEntity.getUuId());
			responseData.setWebUrl(webUrl + "/pages/loseWeight/loseWeight?uuId=" + reduceWeightFundLogEntity.getUuId());
			response.setData(responseData);
		}

		return response;
	}

	@Override
	public BaseDataResDto<RecordWeightResData> userDrawReduceWeightFund(BaseDataReqDto<String> param, String maijiToken)
			throws Exception {
		logger.info("UserServiceImpl.userDrawReduceWeightFund ,param is {}", JSON.toJSONString(param));

		String reduceWeightFundLogId = param.getData();
		if (StringUtils.isBlank(reduceWeightFundLogId))
			return new BaseDataResDto<RecordWeightResData>(Status.PARAMETERERROR);

		ReduceWeightFundLogEntity reduceWeightFundLogEntity = reduceWeightFundLogMapper
				.selectById(reduceWeightFundLogId);

		if (reduceWeightFundLogEntity == null)
			return new BaseDataResDto<RecordWeightResData>(Status.PARAMETERERROR);
		
		if(reduceWeightFundLogEntity.getIsBaseFund() == CommonIntValueEnum.REDUCE_WEIGHT_FUND_LOG_IS_BASE_FUND_HAVE.getValue())return new BaseDataResDto<RecordWeightResData>(Status.PARAMETERERROR,"已经领取");

		reduceWeightFundLogEntity.setIsBaseFund(CommonIntValueEnum.REDUCE_WEIGHT_FUND_LOG_IS_BASE_FUND_HAVE.getValue());
		// 修改为已经领取
		reduceWeightFundLogMapper.updateById(reduceWeightFundLogEntity);

		DistributeFundReqDto distributeFundReqDto = new DistributeFundReqDto();
		DistributeFundReqData distributeFundReqData = distributeFundReqDto.dataInstance();
		distributeFundReqData.setFund(reduceWeightFundLogEntity.getMoney());
		distributeFundReqData.setRelevantId(reduceWeightFundLogEntity.getUuId());
		distributeFundReqData.setRemark(FlowTypeEnum.BASE_LOSE_WEIGHT_FUND);

		distributeFundReqDto.setData(distributeFundReqData);
		// 远程调用分发积分接口
		Boolean bool = integralService.distributeFundByToken(distributeFundReqDto, maijiToken);
		if (!bool) {
			throw new Exception("抛出结算异常");
		}
		BaseDataResDto<RecordWeightResData> response = new BaseDataResDto<RecordWeightResData>(Status.SUCCESS);
		RecordWeightResData data = new RecordWeightResData();
		BeanUtils.copyProperties(reduceWeightFundLogEntity, data);
		response.setData(data);

		return response;
	}

	@Override
	public BaseDataResDto<Boolean> todaySignInResult(String maijiToken) throws Exception {
		logger.info("UserServiceImpl.todaySignInResult ,maijiToken is {}", maijiToken);
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.todaySignInResult ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<Boolean>(Status.ERROR);
		}

		UserSignInEntity userSignInEntity = userSignInMapper.selectOneByUserId(appUser.getUuId());

		if (userSignInEntity != null && userSignInEntity.getInTime().getTime() >= TimeUtil.getZeroTime(new Date()).getTime())
			return new BaseDataResDto<Boolean>(Status.SUCCESS).setData(true);

		return new BaseDataResDto<Boolean>(Status.SUCCESS).setData(false);
	}

	@Override
	public BaseDataResDto<MessageInfoResData> getUserStageMessageInfo(String maijiToken) throws Exception {
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.getUserStageMessageInfo ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<MessageInfoResData>(Status.ERROR);
		}

		UserStageEntity userStageEntity = userStageMapper.selectOneByUserId(appUser.getUuId());

		MessageInfoResData messageInfoResData = new MessageInfoResData();
		Map<Integer,String>  map = new HashMap<Integer,String>();

		if (userStageEntity != null) {
			
			if(userStageEntity.getCurrentStage() == CommonIntValueEnum.STAGE_FOUR.getValue())return new BaseDataResDto<MessageInfoResData>(Status.SUCCESS).setData(messageInfoResData);

			// 当前所处天数
			Integer currentDay = TimeUtil.daysBetween(userStageEntity.getInTime(), new Date()) + 1;
			StageConfigEntity stageConfigEntity = stageConfigMapper.selectOneByStage(userStageEntity.getCurrentStage());
			
			if (stageConfigEntity != null) {

				LoginLog loginLog = loginLogMapper.selcetOneByUserId(appUser.getUuId());

				if (TimeUtil.daysBetween(loginLog.getLoginTime(), new Date())  >= longTimeLogIn) {
					messageInfoResData.setIsShow(true);
					messageInfoResData.setMessageType(MessageTypeEnum.MESSAGE_TYPE_THREE.getKey());
					messageInfoResData.setMessageInfo(MessageTypeEnum.MESSAGE_TYPE_THREE.getValue());
					map.put(MessageTypeEnum.IS_SKIP.getKey(), MessageTypeEnum.IS_SKIP.getValue());
					map.put(MessageTypeEnum.IS_RESTART.getKey(), MessageTypeEnum.IS_RESTART.getValue());
					messageInfoResData.setMap(map);
					return new BaseDataResDto<MessageInfoResData>(Status.SUCCESS).setData(messageInfoResData);
				}

				switch (userStageEntity.getCurrentStage()) {
				case 1:
					if (userStageEntity.getIsExtension() == 1
							&& currentDay > stageConfigEntity.getExtensionDays() + stageConfigEntity.getDays()) {
						messageInfoResData.setIsShow(true);
						messageInfoResData.setMessageType(MessageTypeEnum.MESSAGE_TYPE_TWO.getKey());
						messageInfoResData.setMessageInfo(MessageTypeEnum.MESSAGE_TYPE_TWO.getValue());
						map.put(MessageTypeEnum.IS_SKIP.getKey(), MessageTypeEnum.IS_SKIP.getValue());
						messageInfoResData.setMap(map);
						return new BaseDataResDto<MessageInfoResData>(Status.SUCCESS).setData(messageInfoResData);
					}

					if (userStageEntity.getIsExtension() == 0 && currentDay > stageConfigEntity.getDays()
							&& currentDay < stageConfigEntity.getExtensionDays() + stageConfigEntity.getDays()) {
						messageInfoResData.setIsShow(true);
						messageInfoResData.setMessageType(MessageTypeEnum.MESSAGE_TYPE_ONE.getKey());
						messageInfoResData.setMessageInfo(MessageTypeEnum.MESSAGE_TYPE_ONE.getValue());
						map.put(MessageTypeEnum.IS_SKIP.getKey(), MessageTypeEnum.IS_SKIP.getValue());
						map.put(MessageTypeEnum.IS_EXTENSION.getKey(), MessageTypeEnum.IS_EXTENSION.getValue());
						messageInfoResData.setMap(map);
						return new BaseDataResDto<MessageInfoResData>(Status.SUCCESS).setData(messageInfoResData);
					} else if (userStageEntity.getIsExtension() == 0
							&& currentDay > stageConfigEntity.getExtensionDays() + stageConfigEntity.getDays()) {
						messageInfoResData.setIsShow(true);
						messageInfoResData.setMessageType(MessageTypeEnum.MESSAGE_TYPE_TWO.getKey());
						messageInfoResData.setMessageInfo(MessageTypeEnum.MESSAGE_TYPE_TWO.getValue());
						map.put(MessageTypeEnum.IS_SKIP.getKey(), MessageTypeEnum.IS_SKIP.getValue());
						messageInfoResData.setMap(map);
						return new BaseDataResDto<MessageInfoResData>(Status.SUCCESS).setData(messageInfoResData);
					}
					break;
				case 2:
					if (currentDay > stageConfigEntity.getDays() && userStageEntity.getIsExtension() == 0) {
						messageInfoResData.setIsShow(true);
						messageInfoResData.setMessageType(MessageTypeEnum.MESSAGE_TYPE_FIVE.getKey());
						messageInfoResData.setMessageInfo(MessageTypeEnum.MESSAGE_TYPE_FIVE.getValue());
						map.put(MessageTypeEnum.IS_SKIP.getKey(), MessageTypeEnum.IS_SKIP.getValue());
						map.put(MessageTypeEnum.IS_EXTENSION.getKey(), MessageTypeEnum.IS_EXTENSION.getValue());
						messageInfoResData.setMap(map);
						return new BaseDataResDto<MessageInfoResData>(Status.SUCCESS).setData(messageInfoResData);
					}

					break;
				case 3:
					if (currentDay > stageConfigEntity.getDays() && userStageEntity.getIsExtension() == 0) {
						messageInfoResData.setIsShow(true);
						messageInfoResData.setMessageType(MessageTypeEnum.MESSAGE_TYPE_SIX.getKey());
						messageInfoResData.setMessageInfo(MessageTypeEnum.MESSAGE_TYPE_SIX.getValue());
						map.put(MessageTypeEnum.IS_SKIP.getKey(), MessageTypeEnum.IS_SKIP.getValue());
						messageInfoResData.setMap(map);
						return new BaseDataResDto<MessageInfoResData>(Status.SUCCESS).setData(messageInfoResData);
					}
					break;
			
			}
				}

		}

		return new BaseDataResDto<MessageInfoResData>(Status.SUCCESS).setData(messageInfoResData);
	}

	@Override
	public BaseDataResDto<String> confirmMessageOperation(BaseDataReqDto<Integer> param,String maijiToken) {
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.confirmMessageOperation ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<String>(Status.ERROR);
		}
		UserStageEntity userStageEntity = userStageMapper.selectOneByUserId(appUser.getUuId());
		if(userStageEntity == null)return new BaseDataResDto<String>(Status.ERROR);
		
		
		//跳过此阶段
		if(MessageTypeEnum.IS_SKIP.getKey().equals(param.getData()) ) {
			Integer currentStage = userStageEntity.getCurrentStage()+1;
			userStageEntity = new UserStageEntity();
			userStageEntity.setUuId(UUID_MD5.getUUID());
			userStageEntity.setUserId(appUser.getUuId());
			userStageEntity.setCurrentStage(currentStage);
			userStageEntity.setInTime(new Date());
			userStageMapper.insert(userStageEntity);
			if(userStageEntity.getCurrentStage() == 2)new BaseDataResDto<String>(Status.SUCCESS).setData(MessageTypeEnum.MESSAGE_TYPE_FOUR.getValue());
			if(userStageEntity.getCurrentStage() == 4)new BaseDataResDto<String>(Status.SUCCESS).setData(MessageTypeEnum.MESSAGE_TYPE_SEVEN.getValue());
		}
		//延长此阶段
		if(MessageTypeEnum.IS_EXTENSION.getKey().equals(param.getData())) {
			userStageEntity.setIsExtension(1);
			userStageMapper.updateById(userStageEntity);
			
		}
		//重新开始麦吉阶段
		if(MessageTypeEnum.IS_RESTART.getKey().equals(param.getData())) {
			userStageEntity = new UserStageEntity();
			userStageEntity.setUuId(UUID_MD5.getUUID());
			userStageEntity.setUserId(appUser.getUuId());
			userStageEntity.setCurrentStage(CommonIntValueEnum.STAGE_ONE.getValue());
			userStageEntity.setInTime(new Date());

			EntityWrapper<UserStageEntity> wrapper = new EntityWrapper<UserStageEntity>();
			wrapper.eq("user_id", appUser.getUuId());
			// 删除之前的阶段记录
			userStageMapper.delete(wrapper);
			userStageMapper.insert(userStageEntity);
			if(userStageEntity.getCurrentStage() == 2)new BaseDataResDto<String>(Status.SUCCESS).setData(MessageTypeEnum.MESSAGE_TYPE_FOUR.getValue());
			if(userStageEntity.getCurrentStage() == 4)new BaseDataResDto<String>(Status.SUCCESS).setData(MessageTypeEnum.MESSAGE_TYPE_SEVEN.getValue());
		}
		
		return  new BaseDataResDto<String>(Status.SUCCESS);
	}

	@Override
	public BaseResDto setPayPassword(BaseDataReqDto<SetPayPasswordReqData> param, String userId) {
		logger.info("UserServiceImpl.setPayPassword ,param is {},userId is {}", JSON.toJSONString(param),userId);
		
		UserInfo userInfo = userInfoMapper.selectOneByUserId(userId);
		if(userInfo == null) return new BaseResDto(Status.PARAMETERERROR);
		
		userInfo.setIdCard(param.getData().getIdCard());
		userInfo.setRealName(param.getData().getRealName());
		userInfo.setPayPassword(UUID_MD5.md5Str(param.getData().getPayPassword()));
		
		userInfoMapper.updateById(userInfo);
		
		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseResDto updatePayPassword(BaseDataReqDto<UpdatePayPasswordReqData> param, String userId) {
		logger.info("UserServiceImpl.updatePayPassword ,param is {},userId is {}", JSON.toJSONString(param),userId);
		
		UserInfo userInfo = userInfoMapper.selectOneByUserId(userId);
		if(userInfo == null) return new BaseResDto(Status.PARAMETERERROR);
		
		if(!userInfo.getPayPassword().equals(UUID_MD5.md5Str(param.getData().getOldPayPassword()))) return new BaseResDto(Status.PARAMETERERROR,"原密码错误");
		
		userInfo.setPayPassword(UUID_MD5.md5Str(param.getData().getNewPayPassword()));
		
		userInfoMapper.updateById(userInfo);
		
		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseDataResDto<Boolean> checkPayPassword(BaseDataReqDto<String> param, String userId) {
		logger.info("UserServiceImpl.checkPayPassword ,param is {},userId is {}", JSON.toJSONString(param),userId);
		
		UserInfo userInfo = userInfoMapper.selectOneByUserId(userId);
		if(userInfo == null) return new BaseDataResDto<Boolean>(Status.PARAMETERERROR);
		
		BaseDataResDto<Boolean> responseData = new BaseDataResDto<Boolean>(Status.SUCCESS);
		responseData.setData(false);
		
		if(userInfo.getPayPassword().equals(UUID_MD5.md5Str(param.getData()))) {
			responseData.setData(true);
		}
		
		return responseData;
	}

	@Override
	public BaseResDto setDistributionRuleConfig(BaseDataReqDto<DistributionRuleConfigEntity> param) {
		
		DistributionRuleConfigEntity distributionRuleConfigEntity = mongoTemplate.findOne(new Query(), DistributionRuleConfigEntity.class, DistributionRuleConfigEntity.TABLE_NAME);
		
		
		if(distributionRuleConfigEntity != null){
			mongoTemplate.remove(distributionRuleConfigEntity, DistributionRuleConfigEntity.TABLE_NAME);
		}
		distributionRuleConfigEntity  = new DistributionRuleConfigEntity();
		BeanUtils.copyProperties(param.getData(), distributionRuleConfigEntity);
		distributionRuleConfigEntity.setUuId(UUID_MD5.getUUID());
		mongoTemplate.save(distributionRuleConfigEntity, DistributionRuleConfigEntity.TABLE_NAME);
		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseResDto endMaiji(String userId) {
		logger.info("UserServiceImpl.endMaiji ,userId is {}",userId);
		
		if(StringUtils.isBlank(userId)) return new BaseResDto(Status.PARAMETERERROR);
		
		userInfoMapper.updateForSet("weight = null", new EntityWrapper<UserInfo>().eq("user_id", userId));
		// 删除之前的阶段记录
		userStageMapper.delete( new EntityWrapper<UserStageEntity>().eq("user_id",userId));
		//删除体重记录
		weightChangeLogMapper.delete(new EntityWrapper<WeightChangeLog>().eq("user_id",userId));
				
		return new BaseResDto(Status.SUCCESS);
	}

	@Override
	public BaseDataResDto<Boolean> isSuccessionRecordWeight(String maijiToken) throws Exception {
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.isSuccessionRecordWeight ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<Boolean>(Status.ERROR);
		}
		
		UserInfo userInfo = userInfoMapper.selectOneByUserId(appUser.getUuId());
		
		Date stageStartTime = userInfo == null ? null : userInfo.getStageStartTime();
		
		EntityWrapper<WeightChangeLog> entityWrapper = new EntityWrapper<WeightChangeLog>();
		entityWrapper.eq("user_id", appUser.getUuId());
		if(stageStartTime != null) {
			entityWrapper.ge("record_time", TimeUtil.date2String(stageStartTime, "yyyy-MM-dd"));
		}
		entityWrapper.orderBy("record_time", true);
		List<WeightChangeLog> list = weightChangeLogMapper.selectList(entityWrapper);
		
		if(list == null || list.size() <= 0 ) return new BaseDataResDto<Boolean>(Status.SUCCESS).setData(true);
		
		Boolean flag = false;
		for(int weightChangeLog = 0;weightChangeLog < list.size();weightChangeLog++) {
			Date time = list.get(weightChangeLog).getRecordTime();
			Date nextTime = new Date();
			if(weightChangeLog + 1 != list.size())  nextTime = list.get(weightChangeLog+1).getRecordTime();
			
			int days = TimeUtil.daysBetween(time,nextTime);
			
			if(days > 1) {
				flag = true;
				break;
			}
			
		}
		
		return new BaseDataResDto<Boolean>(Status.SUCCESS).setData(flag);
	}

	@Override
	public BaseDataResDto<Boolean> isLongTimeNotLogIn(String maijiToken) throws Exception {
		AppUser appUser = appUserService.checkToken(maijiToken);
		if (appUser == null) {
			logger.info("UserServiceImpl.isLongTimeNotLogIn ,appUser is {}", JSON.toJSONString(appUser));
			return new BaseDataResDto<Boolean>(Status.ERROR);
		}
		Boolean flag = false;
		LoginLog loginLog = loginLogMapper.selcetOneByUserId(appUser.getUuId());

		if (TimeUtil.daysBetween(loginLog.getLoginTime(), new Date())  >= longTimeLogIn) {
			flag = true;
		}
		
		return new BaseDataResDto<Boolean>(Status.SUCCESS).setData(flag);
	}
}
